#include "dri.h"
#include "kmm.h"
#include "text_video.h"
#include <string.h>
#include <_stdlib.h>
#include "kstdio.h"
#include "fcntl.h"
#include "dbgio.h"
dri_driver_descriptor_t *pty_dri_desc;
uint32_t active_pty = 0;
KFILE keyboard_loops[7];
uint32_t pty_read(struct vfs_node *node ,uint8_t *buffer ,uint32_t offset ,uint32_t length,uint32_t fflags){
	return read(keyboard_loops[active_pty],buffer,length);
}

uint32_t pty_write(struct vfs_node *node ,uint8_t *buffer ,uint32_t offset ,uint32_t length,uint32_t fflags){
	for (uint32_t ptr=0;ptr < length;ptr++)
		vcputch((char)(*buffer++),node->inode);
	return length;
}

uint32_t ptyv_read(struct vfs_node *node ,uint8_t *buffer ,uint32_t offset ,uint32_t length,uint32_t fflags){
	return 0;//TODO: Somehow patch PTYV trough to CON, until then we use a hardcoded call to display driver
}

uint32_t ptyv_write(struct vfs_node *node ,uint8_t *buffer ,uint32_t offset ,uint32_t length,uint32_t fflags){
	return write(keyboard_loops[active_pty],buffer,length);
}

void pty_create_stdio(int pty_id){
	create_fd(0,FREAD ,pty_id,pty_read ,0);   //STDIN  is a pipe to the pty's input stream
	create_fd(1,FWRITE,pty_id,0,pty_write);   //STDOUT is a pipe to the pty's output stream
	link_fd(get_current_process(),get_current_process(),1,2);		  //STDERR is linked to STDOUT
}

void pty_main(){
	pty_dri_desc = (dri_driver_descriptor_t *) kmalloc(sizeof(dri_driver_descriptor_t));
	/* Set up DRI descriptor */
	strcpy(pty_dri_desc->driver_name,"PTY Driver");
	pty_dri_desc->driver_magic = DRI_DRIVER_MAGIC;
	pty_dri_desc->driver_class = DRI_CLASS_CHAR;
	pty_dri_desc->driver_id    = 1;
	pty_dri_desc->driver_class_desc = (void *) 0;
	pty_dri_desc->init_sci = dri_syscall_initialize;
	pty_dri_desc->driver_main = dri_driver_main_stub;
	/* Register driver with DRI */
	dri_register_driver(pty_dri_desc);
	/* Register devfs handles */
	char *buf = (char *) kmalloc(3);
	for (int pty_id = 0;pty_id < 7;pty_id++){
		char *name = (char *) kmalloc(6);
		strcpy(name,"pty");
		itoa(pty_id,10,buf);
		strcat(name,buf);
		dri_register_specfile(name,VFS_CHARDEVICE_FLAG,pty_id,0x1B6,pty_read,pty_write);
	}
	dri_register_specfile("ptyv",VFS_CHARDEVICE_FLAG,0,0x1B6,ptyv_read,ptyv_write);
	/* Create loopbacks */
	for (int pty_id = 0;pty_id < 7;pty_id++)
		keyboard_loops[pty_id] = create_loop(512);
	kfree(buf);
}
